
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.uupaymuch.controller.util.JeepayKit;
import org.junit.Test;

import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

public class ApiTest {
    // 测试商户信息参数
    private static final String MCH_NO = "M1725523868";
    private static final String APP_SECRET = "77yZ4hGzej9XFpPKEBpkKimuPbnSwZaiiEYodjVedwrfVAHMkk8IIMGfxr2kz0vDdD2Yyk4U9mTcwSdFctEv9StcxZ29NArttUT9jtDlzDzBMamccBzkJ4giAr5ebEUE";
    private static final String MCH_NOTIFY_URL = "http://localhost:27003/api/v1/pay/notify/mchTest";  //通知地址
//    // 商户参数
//    private static final String MCH_NO = "M1726975515";
//    private static final String APP_SECRET = "KJWiqRI5AMHbA1nAEQsmqdHMaLvD5z56ZlBw0GZWCM6QSIanLuuMD8huiKpQjievWkXfHABhnrhIDkCPvAtNP6AkGiDpok1GviIiNvmLYWKnJgpx6WDLlP6FcNo729Fe";
    // 预发-沙箱环境
//    private static final String MCH_NO = "M1727772499";
//    private static final String APP_SECRET = "QrfMOtExB6bfoipfxVQcExGJnYZNImDpXJFFJ60rdng5L8LRTjVKreSlMKNGoMs8IvEDMuGZtcEgL54lX7Jy9xQ8iCz6z2Ynrb1kiXzkSQdS3c7upMuAXP4TOaSZdFS0";
//    private static final String MCH_NOTIFY_URL = "http://47.97.71.85:27003/api/v1/pay/notify/mchTest";  //通知地址
    //正式-test
//    private static final String MCH_NO = "M1726831729";
//    private static final String APP_SECRET = "fqYv30sU4ZMqu0VpiZ0md2CSqG1QzLGuydJoPqosPXAfmDUOGVmykqt6DJ0BlNPdoJ5J8AMrcFqpgn9IqAmBtoqN2AkgNBLLJDfGUb8eUCiJcxXW9yDNh70G5EBnzQtb";
//    private static final String MCH_NOTIFY_URL = "http://47.97.71.85:27003/api/v1/pay/notify/mchTest";  //通知地址

    //正式环境代付身份验证
//    private static final String IDENTITY_NO = "114.438.305-69";
//    private static final String ACCOUNT_NO = "2546416839czh@gmail.com";
    //测试环境代付身份验证
    private static final String IDENTITY_NO_TEST = "40959375805";
    private static final String ACCOUNT_NO_TEST = "fc470f19-7a03-4f45-827f-6dc8cda78e68";

    //API地址     印度环境：https://admin.ssonicpay.com:27003/     正式环境：https://fd1.66u6.com/       测试环境：http://47.97.71.85:27003/
    private static final String BASE_URL = "http://localhost:27003/";      //http://192.168.50.244:27003/
    private static final String PAY_URL = BASE_URL + "api/v1/pay/brazil/order";
    private static final String PAY_QUERY_URL = BASE_URL + "api/v1/pay/brazil/queryOrder";
    private static final String TRANSFER_URL = BASE_URL + "api/v1/pay/brazil/transferOrder";
    private static final String TRANSFER_QUERY_URL = BASE_URL + "api/v1/pay/brazil/transfer/query";
    private static final String REFUND_URL = BASE_URL + "api/v1/pay/brazil/refund/refundOrder";
    private static final String REFUND_QUERY_URL = BASE_URL + "api/v1/pay/brazil/refund/query";
    private static final String GET_BALANCE_URL = BASE_URL + "api/v1/pay/brazil/queryMchAccount";
    private static final String CERT_QUERY_URL = BASE_URL + "api/v1/pay/brazil/transferCert/query";

    /**
     * 支付订单
     */
    @Test
    public void payOrder() {
        for (int i = 0; i <100; i++) {
            // 商户单号
            String mchOrderNo = "ZF_TEST_" + System.currentTimeMillis() + ThreadLocalRandom.current().nextInt(1000);
            // 金额
            String amount = String.valueOf(RandomUtil.randomDouble(200,2, RoundingMode.UP));

            HttpRequest request = request(PAY_URL);

            Map<String, Object> paramsMap = createBaseParams();
            paramsMap.put("mchOrderNo", mchOrderNo);
            paramsMap.put("amount", amount);
            paramsMap.put("subject", "ThisIsOrderTitle");
            paramsMap.put("debtorName", "测试付款人姓名");
            paramsMap.put("debtorDocumentNumber", "04870348306");    //CPF号
            paramsMap.put("body", "ThisIsOrderDesc");
            paramsMap.put("currency", "BRL");
            paramsMap.put("notifyUrl", MCH_NOTIFY_URL);

            //获取签名并填充为请求参数
            String bodyString = executeBody(paramsMap);

            doRequest(request.body(bodyString, "application/json"));
        }
    }

    /**
     * 查询支付订单，payOrderId和mchOrderNo二选一即可
     */
    @Test
    public void queryPayOrder() {
        for (int i = 0; i <100; i++) {

            HttpRequest request = request(PAY_QUERY_URL);

            Map<String, Object> paramsMap = createBaseParams();
            //paramsMap.put("payOrderId", "WD1727513872100M1727232350RU3PH");
            paramsMap.put("mchOrderNo", "ZF_TEST_1728385949658230");
            String bodyString = executeBody(paramsMap);
            doRequest(request.body(bodyString, "application/json"));
        }
    }

    /**
     * 代付
     */
    @Test
    public void transferTest() {
        for (int i = 0; i < 200; i++) {

            HttpRequest request = request(TRANSFER_URL);

            String amount = String.valueOf(RandomUtil.randomDouble(200, 1, RoundingMode.UP));
            String mchOrderNo = "DF_TEST_" + System.currentTimeMillis() + ThreadLocalRandom.current().nextInt(1000);
            Map<String, Object> paramsMap = createBaseParams();
            paramsMap.put("amount", amount);
            paramsMap.put("mchOrderNo", mchOrderNo);
            paramsMap.put("currency", "BRL");
            paramsMap.put("identityType", "CPF");    //出款类型
            paramsMap.put("identityNo", IDENTITY_NO_TEST);  // 身份识别号
            paramsMap.put("accountNo", ACCOUNT_NO_TEST);
            //paramsMap.put("transferDesc", "This is Description of the transfer and amount:" + amount);
            paramsMap.put("transferDesc", "This is Description of the transfer");
            paramsMap.put("notifyUrl", "http://123.123.com");

            String bodyString = executeBody(paramsMap);
            doRequest(request.body(bodyString, "application/json"));
        }
    }

    /**
     * 查询代付订单，transferId和mchOrderNo二选一即可
     */
    @Test
    public void queryTransfer() {
        HttpRequest request = request(TRANSFER_QUERY_URL);

        Map<String, Object> paramsMap = createBaseParams();
        //paramsMap.put("transferId", "T1839226464930447361");
        paramsMap.put("mchOrderNo", "MCH_ORDER_1727576726015623");

        String bodyString = executeBody(paramsMap);
        doRequest(request.body(bodyString, "application/json"));
    }

    /**
     * 退款
     * payOrderId和mchOrderNo二选一即可
     */
    @Test
    public void refundTest() {
        List<String> arr = new ArrayList<>(Arrays.asList(
                "WD1728479394620M1726975515ROBKO",
                "WD1728479393331M1726975515R2QYY",
                "WD1728479394503M1726975515RC5CT",
                "WD1728479393450M1726975515R28LX",
                "WD1728479394505M1726975515R3W6O"
        ) );

        for (String payOrderId : arr) {
            HttpRequest request = request(REFUND_URL);

            String mchOrderNo = "TK_TEST_" + System.currentTimeMillis() + ThreadLocalRandom.current().nextInt(1000);

            Map<String, Object> paramsMap = createBaseParams();
            paramsMap.put("payOrderId", payOrderId);
            //paramsMap.put("mchOrderNo", "06604450842942774590");
            paramsMap.put("mchRefundNo", mchOrderNo);    //商户退款订单号
            paramsMap.put("refundAmount", "88.19");   //退款金额，必须与订单金额一致
            paramsMap.put("currency", "BRL");
            paramsMap.put("refundReason", "This is the reason of the refund");
            //paramsMap.put("notifyUrl", MCH_NOTIFY_URL);

            String bodyString = executeBody(paramsMap);
            doRequest(request.body(bodyString, "application/json"));
        }

    }

    /**
     * 查询退款订单，refundId和mchRefundNo二选一即可
     */
    @Test
    public void queryRefund() {
        HttpRequest request = request(REFUND_QUERY_URL);

        Map<String, Object> paramsMap = createBaseParams();
        paramsMap.put("refundOrderId", "R1843611087336747010");
        //paramsMap.put("mchRefundNo","REFUND_ORDER_1727421926308220");

        String bodyString = executeBody(paramsMap);
        doRequest(request.body(bodyString, "application/json"));
    }

    /**
     * 获取余额
     */
    @Test
    public void getBalance() {
        HttpRequest request = request(GET_BALANCE_URL);
        Map<String, Object> paramsMap = createBaseParams();
        paramsMap.put("currency", "BRL");

        String bodyString = executeBody(paramsMap);
        doRequest(request.body(bodyString, "application/json"));
    }

    /**
     * 查询代付凭证，transferId和mchOrderNo二选一即可
     */
    @Test
    public void queryVoucher() {
        HttpRequest request = request(CERT_QUERY_URL);

        Map<String, Object> paramsMap = createBaseParams();
        paramsMap.put("transferId", "T1839590389081554946");
        //paramsMap.put("mchOrderNo","TEST_ORDER_1727427500824803");

        String bodyString = executeBody(paramsMap);
        doRequest(request.body(bodyString, "application/json"));
    }

    /**
     * 获取公共请求
     *
     * @param url 请求地址
     * @return 请求体
     */
    private static HttpRequest request(String url) {
        HttpRequest request = HttpUtil.createPost(url);
        request.header("Content-Type", "application/json");
        return request;
    }

    /**
     * 创建公共参数
     *
     * @return 基础参数
     */
    private static Map<String, Object> createBaseParams() {
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("mchNo", MCH_NO);
        paramsMap.put("reqTime", System.currentTimeMillis());
        return paramsMap;
    }

    /**
     * 处理请求
     *
     * @param request 请求体
     */
    private static void doRequest(HttpRequest request) {
        try (HttpResponse response = request.execute()) {
            if (200 <= response.getStatus() && response.getStatus() < 300) {
                //assertSign(response);
                // 请求成功，处理响应
                System.out.println("Response Code: " + response.getStatus());
                System.out.println("Response Body: " + response.body());
            } else {
                // 请求失败
                System.out.println(response);
                System.out.println("Request failed with code: " + response.getStatus());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 验证返回签名是否正确
     * @param response 请求响应结果
     */
//    private static void assertSign(HttpResponse response){
////        System.out.println(response);
//        if (!JsonUtil.getValue(BaseUtil.getResult(response),"code").equals("0")){
//            return;
//        }
//        String responseSign = JsonUtil.getValue(BaseUtil.getResult(response),"sign");
//        System.out.println("返回签名：" + responseSign);
//
//        //获取返回参数用于计算签名
//        Map data = JSON.parseObject(JsonUtil.getValue(BaseUtil.getResult(response),"data"),Map.class);
//
//        String assertSign = JeepayKit.getSign(data,APP_SECRET);
//        System.out.println("未去除channelRetMsg时的签名" + assertSign);
//        System.out.println(assertSign);
//
//        if (data.containsKey("channelRetMsg")){
//            data.remove("channelRetMsg");
//        }
//        String assertSign1 = JeepayKit.getSign(data,APP_SECRET);
//        System.out.println("去除channelRetMsg后的签名" + assertSign1);
//        if(responseSign.equals(assertSign)){
//            System.out.println("验签成功=================");
//        }else {
//            System.out.println("验签失败=================");
//        }
//    }

    /**
     * 生成签名并填入请求参数中
     *
     * @param paramsMap 请求参数
     * @return 加签后的请求参数
     */
    private static String executeBody(Map<String, Object> paramsMap) {
        String jsonOutput;
        try {
            // 将 HashMap 转换为 JSONObject
            JSONObject bizReqJSON = new JSONObject(paramsMap);
            // 获取签名
            String sign = JeepayKit.getSign(bizReqJSON, APP_SECRET);
            // 设置签名到参数 map 中
            paramsMap.put("sign", sign);
            // 将 HashMap 转换为 JSON 并输出
            jsonOutput = JSON.toJSONString(paramsMap);
        } catch (Exception e) {
            System.out.println("生成签名字符串时发生错误: " + e.getMessage());
            throw new RuntimeException(e);
        }
        System.out.println("测试JSON" + jsonOutput);
        return jsonOutput;
    }
}

